package org.restql.db.operation;

import java.io.PrintWriter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.restql.webapp.RestQLException;
import org.restql.db.resource.DatabaseResource;
import org.restql.db.resource.RequestResource;
import org.restql.webapp.output.XmlPrinter;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

public class DatabaseSelect extends DatabaseGet {

	public DatabaseSelect(DatabaseResource databaseResource, RequestResource requestResource) {
		super(databaseResource, requestResource);
	}

	private static Log logger = LogFactory.getLog(DatabaseSelect.class);

	public void executeSql(PrintWriter printer) throws RestQLException {
		try {
			String constructedSQL =
				databaseResource.getSelectString(this.requestResource) + " " +
				databaseResource.getFromString(this.requestResource) + " " +
				databaseResource.getWhereString(this.requestResource);

			// Execute SQL query
			PreparedStatement stmt =
				getConnection().prepareStatement(constructedSQL);

			logger.info("Executing: " + constructedSQL);

			ResultSet rs = stmt.executeQuery();
			Map<String, String> colTypes = getColInfo(rs);
			Document doc = buildDOM(rs, colTypes.keySet());
			XmlPrinter.printXml(doc, printer);

		} catch (SQLException e) {
			logger.info(e.getMessage());
			throw new RestQLException("Error executing select query", e);
		} catch (ParserConfigurationException e) {
			throw new RestQLException("Error building dom", e);
		} catch (TransformerException e) {
			throw new RestQLException("Error printing dom", e);
		}
	}

	protected Document buildDOM(ResultSet rs, Set<String> colNames) throws SQLException, ParserConfigurationException {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.newDocument();

		Element root = doc.createElement(this.requestResource.getDbName());
		doc.appendChild(root);

		while (rs.next()) {
			Element tableRow = doc.createElement(this.requestResource.getResourceName());
			root.appendChild(tableRow);

			for (String colName : colNames) {
				Element fieldElement = doc.createElement(colName);
				String fieldValue = rs.getString(colName);
				if (fieldValue != null) {
					Text t = doc.createTextNode(fieldValue);
					fieldElement.appendChild(t);
					tableRow.appendChild(fieldElement);
				}
			}
		}
		return doc;
	}


}
